同一人講不同話,再轉成 Mel 之後還是不同的東西,那我們又該如何判斷出一句話是哪個人講的呢 ?
有了 GMM 之後,接著又延伸出了 i-vector 的演算法,相對於 GMM 這種生成模型是類別確定的 (類別之外的無法被 GMM 處理,實際上也不可能訓練一個全人類的聲音分類器),i-vector 它轉而去尋找一個 hidden variable space,讓每個人都是這個空間里的一員。
到這裡傳統的做法就告一段落了(自己也沒有深入去研究怎麼算的 XD),但如果你對 GMM 有興趣的化可以參考這篇論文
把它訓練模型寫出來就長這個樣子
# class 看你用幾種
def build_model(input_size,hidden_size = 256,n_class = 5):
model = Sequential(
[
Dense(hidden_size,input_shape=(input_size,)),
Activation('relu'),
########################
Dense(hidden_size),
Activation('relu'),
Dropout(0.5),
Dense(hidden_size),
Activation('relu'),
Dropout(0.5),
###################################
# D_VECTOR 的源頭就在下面這一層提出來 #
###################################
Dense(dim_emb,name="class_dense"),
Activation('softmax')
]
)
return model
在訓練的時候輸入 x 就是語音的特徵 (梅爾倒頻係數或是你可以參考 paper 的作法),目標 y 則是類別標籤,loss 採用 categorical_crossentropy
在評估的時候輸入 x 只通過最後一層 Dense 再把結果做 L2 norm 然後累加出來做平均(或是 PCA)就煉成了 D-VECTOR,也就是 Speaker Embedding。
當然 D_VECTOR 的模型也有許多變體,像是你可以把 Dense 改 LSTM,或是用 Convlution 去達成,我們上面做的是最古老的版本。
比方說現在有 N 個不同的人,模型也照這五人訓練了,那要怎麼評估模型有用呢?
從這 N 人的測試資料集算出平均的 D-VECTOR
從這 N 人再取不在資料集的語音算 D-VECTOR
計算兩 D-VECTOR 的 Cosin 距離,各自對應的都該是最短距離
from sklearn.metrics.pairwise import cosine_similarity
result = []
# ave_dv 有 5 人的平均 D-VECTOR
for test_dv in ave_dv:
tmp = []
# valid_dvs 有 5 人不在資料集的 D-VECTOR
for valid_dv in valid_dvs:
res = cosine_similarity([test_dv], [valid_dv])
tmp.append(res)
result.append(tmp)
今天我們簡單介紹也實做了 D_VECTOR ,明天開始我們終於要正式進入聲音轉換的部分了!
颱風要來了,大家記得做個防颱準備吧!
D_Vector Implement
D_Vector Paper